package com.github.llyb120.binscript;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharUtil;
import javassist.compiler.Lex;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class Lexer {

    private char[] code;
    private int length;
    private int pos;
    private int _pos;
    private boolean inToken = false;
    private char[] buffer = new char[10];

    /**
     * 字符串定界符
     */
    private char strSplit = ' ';

    public Lexer(String str) {
        this.code = (str + " ").toCharArray();
        this.length = code.length;
        this.pos = 0;
        this.lex();
    }


    public void lex() {
        while (pos < length) {
            char c = (char) code[pos];
            loop:
            {
                if(isInStr()){
                    if(c == '\\'){
                        pos++;
                    } else {
                        if(c == strSplit){
                            //str end
                            String token = readToken();
                        }
                    }
                    break loop;
                }
                boolean isSymbol = isSymbol(c);
                boolean isBlank = CharUtil.isBlankChar(c);
                if(inToken && (isSymbol || isBlank)){
                    String token = readToken();
                    if(isSymbol){
                        String symbol = readSymbol();
                    }
                    break loop;
                }
                if(!inToken && isSymbol){
                    String symbol = readSymbol();
                    break loop;
                }

                if(!isBlank && !inToken){
                    //字符开始
                    if(c == '\'' || c == '"'){
                        strSplit = c;
                        mark(pos + 1);
                    } else {
                        mark();
                    }
                    inToken = true;
                }

            }
            pos++;
        }
    }

    private String readSymbol(){
        int i = 0;
        int count = 1;
        for(; pos < length; pos++, i++){
            if(i == 0){
                buffer[i] = code[pos];
            } else {
                if(isSymbol(code[pos])) {
                    buffer[i] = code[pos];
                    if(canLink(buffer[i - 1], buffer[i])) {
                        //只有能继续链接的才可以往下
                        count++;
                    } else {
                        pos--;
                        break;
                    }
                } else {
                    pos--;
                    break;
                }
            }
        }
        String token =  new String(buffer, 0, count);
        System.out.println(token);
        return token;
    }

    private boolean canLink(char pre, char post){
        return ((pre == '=' || pre == '>' || pre == '<') && post == '=');
    }

    private String readToken(){
        String token;
        token = new String(code, _pos, pos - _pos);
        inToken = false;
        _pos = -1;
        strSplit = ' ';
        System.out.println(token);
        return token;
    }

    private void mark(){
        this._pos = pos;
    }

    private void mark(int pos){
        this._pos = pos;
    }

    /**
     * 是否正在构建字符串
     *
     * @return
     */
    private boolean isInStr(){
        return inToken && strSplit != ' ';
    }

    private boolean isSymbol(char c){
        return c == ';' || c == '=' || c == '\n' || c == '(' || c == ')' || c == ':' || c == '{' || c == '}' || c == ',' || c =='[' || c == ']' || c == '+' || c == '-' || c == '*' || c == '/' || c == '.' || c == '<' || c == '>';
    }

    public static void main(String[] args) {
        new Lexer(FileUtil.readUtf8String("D:\\work\\cal-engine\\src\\main\\resources\\test.js"));
    }
}
